#include <iostream>
#include <memory>
#include <vector>
#include <string>

// 演示内存错误（仅用于教学，不要在实际代码中这样做！）
void demonstrateMemoryErrors() {
    std::cout << "=== 常见内存错误演示 ===" << std::endl;
    
    std::cout << "1. 内存泄漏示例（已注释，避免实际泄漏）:" << std::endl;
    // 错误做法：
    // int* numbers = new int[1000]; // 分配内存但从不释放
    // return; // 函数结束，指针丢失，内存泄漏！
    
    std::cout << "正确做法：使用智能指针或栈分配" << std::endl;
    auto numbers = std::make_unique<int[]>(1000); // 自动管理内存
    
    std::cout << "\n2. 重复释放示例（已注释，避免崩溃）:" << std::endl;
    // 错误做法：
    // int* ptr = new int(42);
    // delete ptr;
    // delete ptr; // 重复释放！程序崩溃
    
    std::cout << "正确做法：使用智能指针，或释放后置空" << std::endl;
    
    std::cout << "\n3. 使用悬挂指针示例（已注释，避免未定义行为）:" << std::endl;
    // 错误做法：
    // int* ptr = new int(42);
    // delete ptr;
    // std::cout << *ptr; // 使用已释放的内存！
    
    std::cout << "正确做法：释放后不再使用，或使用智能指针" << std::endl;
}

// 正确的内存管理实践
class BestPracticesDemo {
private:
    std::vector<std::unique_ptr<std::string>> strings;
    std::shared_ptr<std::vector<int>> sharedData;
    
public:
    BestPracticesDemo() {
        // 使用 make_shared 创建共享数据
        sharedData = std::make_shared<std::vector<int>>();
        
        // 预分配一些数据
        for (int i = 0; i < 5; ++i) {
            sharedData->push_back(i * 10);
        }
        
        std::cout << "BestPracticesDemo 创建完成" << std::endl;
    }
    
    void addString(const std::string& str) {
        // 使用 make_unique 创建独占所有权的字符串
        strings.push_back(std::make_unique<std::string>(str));
    }
    
    void printStrings() const {
        std::cout << "存储的字符串:" << std::endl;
        for (const auto& str : strings) {
            std::cout << "  - " << *str << std::endl;
        }
    }
    
    std::shared_ptr<std::vector<int>> getSharedData() const {
        return sharedData; // 返回共享指针，安全地共享数据
    }
    
    // 析构函数不需要手动清理，智能指针会自动处理
    ~BestPracticesDemo() {
        std::cout << "BestPracticesDemo 销毁，包含 " 
                  << strings.size() << " 个字符串" << std::endl;
    }
};

void demonstrateBestPractices() {
    std::cout << "\n=== 内存管理最佳实践 ===" << std::endl;
    
    {
        BestPracticesDemo demo;
        demo.addString("第一个字符串");
        demo.addString("第二个字符串");
        demo.addString("第三个字符串");
        
        demo.printStrings();
        
        // 获取共享数据
        auto data = demo.getSharedData();
        std::cout << "共享数据大小: " << data->size() << std::endl;
        std::cout << "共享数据引用计数: " << data.use_count() << std::endl;
        
        // 即使 demo 对象被销毁，data 仍然有效
    } // demo 在这里被销毁
    
    std::cout << "demo 对象已销毁，但内存管理是安全的" << std::endl;
}

// 内存管理指导原则
void printMemoryManagementGuidelines() {
    std::cout << "\n=== C++ 内存管理黄金法则 ===" << std::endl;
    std::cout << "1. 优先使用栈分配而不是堆分配" << std::endl;
    std::cout << "2. 必须使用堆时，优先使用智能指针" << std::endl;
    std::cout << "3. 使用 make_unique 和 make_shared 创建智能指针" << std::endl;
    std::cout << "4. 避免裸指针管理内存（除非与 C 库交互）" << std::endl;
    std::cout << "5. 遵循 RAII 原则：构造时获取资源，析构时释放资源" << std::endl;
    std::cout << "6. 使用容器（vector, string, array）代替原始数组" << std::endl;
    std::cout << "7. 不要手动调用 new/delete，让智能指针处理" << std::endl;
}

int main() {
    demonstrateMemoryErrors();
    demonstrateBestPractices();
    printMemoryManagementGuidelines();
    
    std::cout << "\n 程序结束，所有内存都被正确管理！" << std::endl;
    return 0;
}